package com.swordliu.auto_email;

import freemarker.template.Configuration;
import freemarker.template.TemplateException;
import org.springframework.core.io.FileSystemResource;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.ui.freemarker.FreeMarkerConfigurationFactoryBean;
import org.springframework.ui.freemarker.FreeMarkerTemplateUtils;

import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import java.io.File;
import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

/**
 * Created by SwordLiu on 2017-06-21.
 */
public class Email {

    /**
     * 发送普通文本邮件，及时加入样式标签也无用，会原样发送出去
     */
    public void sendSimpleMail() {


        JavaMailSenderImpl javaMailSender = getSender();

        SimpleMailMessage simpleTextMessage = new SimpleMailMessage();
        simpleTextMessage.setFrom("123@qq.com");      //发送者
        simpleTextMessage.setTo("456@qq.com");        //接受者
        String subject = "这是普通文本邮件";     //邮件主题
        simpleTextMessage.setSubject(subject);
        String content = "<p>无聊的时候发发邮件，可以缓解疲劳~！</p>   <p>from 建哥~！</p>";     //邮件内容
        simpleTextMessage.setText(content);
        Date sendDate = new Date();     //发送时间
        simpleTextMessage.setSentDate(sendDate);

        //发送
        javaMailSender.send(simpleTextMessage);

    }

    /**
     * 发送HTML超文本邮件
     * 邮件内容里的样式标签会转换成样式后发送，可以是从前台文本编辑器获取的内容:可以包含  超链接  图片 ……
     */
    public void sendHtmlMail() {
        // 建立邮件消息,发送简单邮件和html邮件的区别
        JavaMailSenderImpl javaMailSender = getSender();
        MimeMessage mailMessage = javaMailSender.createMimeMessage();
        // 为防止乱码，添加编码集设置
//        MimeMessageHelper messageHelper = new MimeMessageHelper(mailMessage, "UTF-8");

        try {
            //发送本地文件内嵌入文本才需要创建该helper
            MimeMessageHelper messageHelper = new MimeMessageHelper(mailMessage, true);

            messageHelper.setFrom("123@qq.com");
            messageHelper.setTo("456@qq.com");
            messageHelper.setSubject("这是html格式邮件");
//            String context = "<p>你好：</p><p>这是带格式的文本</p>";
            //嵌入图片：http://pic6.huitu.com/res/20130116/84481_20130116142820494200_1.jpg
//            String context = "<html><head></head><body><h1>下面是一张图片</h1>"
//                    +"<a href=http://www.baidu.com>baidu</a>"	+ "<img src='http://pic6.huitu.com/res/20130116/84481_20130116142820494200_1.jpg' /></body></html>";

            //或者是本地图片内嵌入文本
            String context = "<p>你好：</p><p><img src=cid:image/></p>";
            FileSystemResource fileSystemResource = new FileSystemResource(new File("image/img.jpg"));
            messageHelper.addInline("image" ,fileSystemResource);   //在文本内加入图片

            messageHelper.setText(context,true);
            messageHelper.setSentDate(new Date());
        } catch (MessagingException e) {
            e.printStackTrace();
        }

        javaMailSender.send(mailMessage);
    }

    /**
     * 发送包含附件或者是内嵌图片的邮件
     */
    public void sendEnclosureMail() {
        // 建立邮件消息,发送简单邮件和html邮件的区别
        JavaMailSenderImpl javaMailSender = getSender();
        MimeMessage mailMessage = javaMailSender.createMimeMessage();

        try {
            //发送本地文件内嵌入文本才需要创建该helper
            MimeMessageHelper messageHelper = new MimeMessageHelper(mailMessage, true);

            messageHelper.setFrom("123@qq.com");
            messageHelper.setTo("4@qq.com");//大柜子
            messageHelper.setCc("456@qq.com");//这是抄送的邮件，会显示出来
            messageHelper.setBcc("456@qq.com");//这是抄送的邮件，但是不会显示出来
            messageHelper.setSubject("这是带附件的邮件,并抄送给很多人");
            String context = "<p>你好：</p><p><img src=\"cid:image\" /></p>";

            //添加文件到附件
            //FileSystemResource ,或者用下一个方法的类加载器来定位路径
            FileSystemResource fileSystemResource = new FileSystemResource(
                    new File("C:\\SwordForJave\\workspace-idea\\spring-email\\src\\main\\resources\\image\\img.jpg"));

            messageHelper.addAttachment("img.jpg" ,fileSystemResource);   //在文本内加入图片

            //这样发送的图片显示不了，发送到邮箱之后，该路径指向的是邮件服务器的地址，服务器是没有这个地址的~！
            //解决方案：使用网络上存在的资源地址
            messageHelper.addInline("image", fileSystemResource);

            messageHelper.setText(context,true);
            messageHelper.setSentDate(new Date());
        } catch (MessagingException e) {
            e.printStackTrace();
        }

        javaMailSender.send(mailMessage);
    }

    public void sendTemplateMail() {
        // 模板邮件
        String img = "<img src=\"https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000" +
                "&sec=1498554000706&di=a268b0767c4771107066756d12eaac0b&imgtype=jpg&src=http%3A%2F%2Fimg0.imgtn." +
                "bdimg.com%2Fit%2Fu%3D2619537094%2C271558696%26fm%3D214%26gp%3D0.jpg\" />";
        Map<String, Object> model = new HashMap<>();
        model.put("from", "SwordLiu");
        model.put("image", img);

        StringBuffer context = new StringBuffer();
        FreeMarkerConfigurationFactoryBean freemarker = new FreeMarkerConfigurationFactoryBean();
        //这是读取类加载路径的方法
        System.out.println("path:"+this.getClass().getClassLoader().getResource("").getPath());
        String text = "";
        try {
            //创建配置文件
            Configuration configuration = freemarker.createConfiguration();
            //设置模版文件路径
            configuration.setClassForTemplateLoading(this.getClass(), "/");
            //读取指定的模版文件，并注入model
            context.append(FreeMarkerTemplateUtils.processTemplateIntoString(configuration.getTemplate(
                    "sendMail.txt"), model));
            text = context.toString();

             //加载模板目录的三种方法
            /*
                第一种：基于类路径，resource下的sendMail.txt文件，先加载的是类路径，也就是resource发布后的路径
                configuration.setClassForTemplateLoading(this.getClass(), "/");
                configuration.getTemplate("sendMail.txt"); //sendMail.txt为要装载的模板

                第二种：基于文件系统--应该是绝对路径（应该是指非项目内的本地文件）
                configuration.setDirectoryForTemplateLoading(new File("/"))
                configuration.getTemplate("sendMail.txt"); //sendMail.txt为要装载的模板

                第三种：基于Servlet Context，指的是基于WebRoot下的template下的sendMail.txt文件
                HttpServletRequest request = ServletActionContext.getRequest();
                configuration.setServletContextForTemplateLoading(request.getSession().getServletContext(), "/");
                configuration.getTemplate("sendMail.txt"); //sendMail.txt为要装载的模板
            */
        } catch (IOException e) {
            e.printStackTrace();
        } catch (TemplateException e) {
            e.printStackTrace();
        }



        JavaMailSenderImpl javaMailSender = getSender();
        MimeMessage mimeMessage = javaMailSender.createMimeMessage();
        try {
            MimeMessageHelper messageHelper = new MimeMessageHelper(mimeMessage, true);
            messageHelper.setFrom("123@qq.com");
            messageHelper.setTo("456@qq.com");
            messageHelper.setCc("1@qq.com");//大柜子
            messageHelper.setSubject("草，终于把模板邮件搞出来了~！MD，网上的太坑了~！");
            messageHelper.setText(text, true);

        } catch (MessagingException e) {
            e.printStackTrace();
        }


        javaMailSender.send(mimeMessage);
    }

    /**
     * sender一般会写入spring 注入
        <bean id="javaMailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
            <property name="defaultEncoding" value="UTF-8" />
            <property name="host" value="smtp.qq.com" />
            <property name="port" value="465" />
            <property name="username" value="123@qq.com" />
            <property name="password" value="kydqkpnsklcmcbde" />

            <property name="javaMailProperties">
                <props>
                    <prop key="mail.smtp.auth">true</prop>
                    <prop key="mail.smtp.timeout">25000</prop>

                    *以下可选
                    <prop key="mail.smtp.socketFactory.class">javax.net.ssl.SSLSocketFactory</prop>
                    <prop key="mail.smtp.port">465</prop>
                    <prop key="mail.smtp.socketFactory.fallback">false</prop>
                    <prop key="mail.smtp.starttls.enable">true</prop>
                    <prop key="mail.transport.protocol">smtp</prop>
                    <prop key="mail.debug">true</prop>
                </props>
            </property>
        </bean>
     * @return
     *
     * @MailAuthenticationException
        org.springframework.mail.MailAuthenticationException: Authentication failed; nested exception is javax.mail.AuthenticationFailedException
        如果遇到该异常，应该先考虑一下你所配的发送邮箱，有没有对外开放POP3/SMTP服务，QQ邮箱有，但是QQ邮箱在默认状态下，也是没有开启这个服务的，
        得自己到“邮箱设置》账户”手动设置开启POP3/SMTP服务，如果是新注册的QQ貌似得等半个月之后才能开启。
     */
    public JavaMailSenderImpl getSender() {

        //加载mailsender
        JavaMailSenderImpl javaMailSender = new JavaMailSenderImpl();
        //设置编码格式，防止乱码，一般不用设置
        javaMailSender.setDefaultEncoding("UTF-8");
        javaMailSender.setHost("smtp.qq.com");
        javaMailSender.setUsername("123@qq.com");
        javaMailSender.setPassword("kydqkpnsklcmcbde");

        Properties properties = new Properties();
        properties.put("mail.smtp.auth", "true");
        properties.put("mail.smtp.timeout", "25000");
        //这里是配置ssl
        properties.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
        properties.put("mail.smtp.port", "465");
        properties.put("mail.smtp.socketFactory.fallback", "false");
        properties.put("mail.smtp.starttls.enable", "true");
        javaMailSender.setJavaMailProperties(properties);

        return javaMailSender;

    }

}
